﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Web;
using PmfWeb.Core.Utility;

namespace PmfWeb.Core
{
    public class ExpireLicense :License
    {
        private Type _type;
        private string _ticks;

        ///<summary>
        /// 构造器
        ///</summary>
        ///<param name="type"></param>
        ///<param name="ticks"></param>
        public ExpireLicense(Type type,string ticks)
        {
            _type = type;
            _ticks = ticks;
        }



        #region License成员
        ///<summary>
        /// 清楚授权信息
        ///</summary>
        public override void Dispose()
        {
            _type = null;
            _ticks = null;
        }

        ///<summary>
        /// 授权信息
        ///</summary>
        public override string LicenseKey
        {
            get { return _ticks; }
        }
        #endregion
    }

    ///<summary>
    /// 控件授权检查提供者
    ///</summary>
    [DebuggerNonUserCode]
    public class ExpireLicenseProvider : LicenseProvider
    {
        private static LisenseDataDictionary _licenses;
        static  readonly  object _lock = new object();


        #region LicenseProvider成员
        ///<summary>
        /// 获取授权信息
        ///</summary>
        ///<param name="context"></param>
        ///<param name="type"></param>
        ///<param name="instance"></param>
        ///<param name="allowExceptions"></param>
        ///<returns></returns>
        ///<exception cref="NotImplementedException"></exception>
        public override License GetLicense(LicenseContext context, Type type, object instance, bool allowExceptions)
        {
            ExpireLicense license = null;
            string errorMessage = null;

            if(context.UsageMode == LicenseUsageMode.Designtime)
            {
                license = new ExpireLicense(type,DateTime.MaxValue.Ticks.ToString());
            }
            else
            {
                license = GetLicenseData(type);

                if(null != license)
                {
                    if(!ValidateLicense(license,out errorMessage))
                    {
                        license = null;
                    }
                }
                else
                {
                    CreateLicenseFile();
                    errorMessage = "飘渺峰提醒您,您当前使用的控件没有获得授权!";
                }
            }
            if(null == license && allowExceptions)
            {
                if (null == errorMessage)
                    throw new LicenseException(type);
                throw new LicenseException(type, instance, errorMessage);
            }
            return license;
        }
        #endregion

        #region 验证授权文件
        /// <summary>
        /// 验证授权文件
        /// </summary>
        /// <param name="license">授权对象</param>
        /// <param name="message">无授权时要显示的错误信息</param>
        /// <returns>是否通过授权</returns>
        protected virtual bool ValidateLicense(ExpireLicense license, out string message)
        {
            message = null;
            bool valided = true;
            try
            {
                DateTime dTime = new DateTime(long.Parse(license.LicenseKey));

                if(dTime <= DateTime.Now)
                {
                    message = "授权已过期!";
                    valided = false;
                }
            }
            catch (FormatException)
            {
                message = "授权文件错误!";
                valided = false;
            }
            return valided;
        }
        #endregion

        protected virtual ExpireLicense GetLicenseData(Type type)
        {
            if(null == _licenses)
            {
                lock (_lock)
                {
                    _licenses = GetLicenseData(type.FullName);
                }
            }
            if(_licenses.ContainsKey(type.FullName))
            {
                if (_licenses != null)
                {
                    long ticks = _licenses[type.FullName];
                   
                    return new ExpireLicense(type, ticks.ToString());
                }
            }
            return null;
        }

        private LisenseDataDictionary GetLicenseData(string type)
        {
            LisenseDataDictionary license = new LisenseDataDictionary();

            if(null != HttpContext.Current)
            {
                string licFilePath = HttpContext.Current.Server.MapPath("~/license.lic");
                if(File.Exists(licFilePath))
                {
                    using (StreamReader reader = File.OpenText(licFilePath))
                    {
                        string line = reader.ReadLine();
                        while (!string.IsNullOrEmpty(line))
                        {
                            string[] data = line.Split(':');
                            if(2 == data.Length && !license.ContainsKey(data[0]))
                                license.Add(DESncrypt.Decrypt(data[0]), long.Parse(DESncrypt.Decrypt(data[1])));
                            line = reader.ReadLine();
                        }
                    }
                }
                else
                {
                    CreateLicenseFile();
                }
            }
            return license;
        }

        ///<summary>
        /// 创建授权文件
        ///</summary>
        ///<returns></returns>
        public virtual bool CreateLicenseFile()
        {
            bool result = false;
            if (null == HttpContext.Current) return false;
            string lisensePath = HttpContext.Current.Server.MapPath("~/license.lic");
            try
            {
                using (StreamWriter writer = File.CreateText(lisensePath))
                {
                    writer.WriteLine(string.Format("{0}:{1}", DESncrypt.Encrypt("PmfWeb.Core.WebControls.Anchor"), DESncrypt.Encrypt(DateTime.Now.AddDays(2 * 7).Ticks.ToString())));
                    //writer.WriteLine(string.Format("{0}:{1}", Common.DESncrypt.Encrypt("PmfWeb.Core.WebControls.Author"), Common.DESncrypt.Encrypt(DateTime.Now.AddDays(2 * 7).Ticks.ToString())));
                    writer.WriteLine(string.Format("{0}:{1}", DESncrypt.Encrypt("PmfWeb.Core.WebControls.Img"), DESncrypt.Encrypt(DateTime.Now.AddDays(2 * 7).Ticks.ToString())));
                    writer.WriteLine(string.Format("{0}:{1}", DESncrypt.Encrypt("PmfWeb.Core.WebControls.Input"), DESncrypt.Encrypt(DateTime.Now.AddDays(2 * 7).Ticks.ToString())));
                    writer.WriteLine(string.Format("{0}:{1}", DESncrypt.Encrypt("PmfWeb.Core.WebControls.Span"), DESncrypt.Encrypt(DateTime.Now.AddDays(2 * 7).Ticks.ToString())));
                    writer.WriteLine(string.Format("{0}:{1}", DESncrypt.Encrypt("PmfWeb.Core.WebControls.TextBox"), DESncrypt.Encrypt(DateTime.Now.AddDays(2 * 7).Ticks.ToString())));
                    //writer.WriteLine(string.Format("{0}:{1}", Common.DESncrypt.Encrypt("PmfWeb.Core.WebControls.Author"), Common.DESncrypt.Encrypt(DateTime.Now.AddDays(2 * 7).Ticks.ToString())));
                    //writer.WriteLine(string.Format("{0}:{1}", Common.DESncrypt.Encrypt("PmfWeb.Core.WebControls.Author"), Common.DESncrypt.Encrypt(DateTime.Now.AddDays(2 * 7).Ticks.ToString())));

                    result = true;
                }
            }
            catch (Exception)
            {
                result = false;
            }
            return result;
        }
    }

    ///<summary>
    /// 许可数据实体
    ///</summary>
    [Serializable]
    public class LisenseDataDictionary : Dictionary<string,long >{}
}
